package com.ruoyi.business.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

/**
 * 描述
 *
 * @author hanxu
 * @date 2025/9/12
 * @since 2025/9/12
 */
public class OSSUtil {

    Logger logger = LoggerFactory.getLogger(OSSUtil.class);
    private OSS ossClient;

    public OSSUtil(String endpoint, String region, String accessKeyId, String accessKeySecret) {
        // 使用DefaultCredentialProvider方法直接设置AK和SK
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
        // 创建 ClientBuilderConfiguration 实例，用于配置 OSS 客户端参数
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 设置签名算法版本为 V4
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        // 设置使用 HTTPS 协议访问 OSS，保证传输安全性
        clientBuilderConfiguration.setProtocol(Protocol.HTTPS);
        // 创建 OSS 客户端实例
        this.ossClient = OSSClientBuilder.create()
                // 以华东1（杭州）地域的外网访问域名为例，Endpoint填写为oss-cn-hangzhou.aliyuncs.com
                .endpoint(endpoint)
                // 从环境变量中获取访问凭证（需提前配置 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET）
                .credentialsProvider(credentialsProvider)
                // 设置客户端配置
                .clientConfiguration(clientBuilderConfiguration)
                // 以华东1（杭州）地域为例，Region填写为cn-hangzhou
                .region(region)
                .build();
    }

    /**
     * 上传文件
     * @param bucketName bucket名称
     * @param objectName 对象名称
     * @param file 上传文件
     * @return 是否上传成功 true 上传成功  false 上传失败
     */
    public boolean uploadFile(String bucketName, String objectName, MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            if ( StringUtils.isNotEmpty(result.getETag()) ) {
                return true;
            }
        } catch (OSSException oe) {
            throw new RuntimeException(oe.getMessage());
        } catch (ClientException ce) {
            throw new RuntimeException(ce.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return false;
    }

    /**
     * 上传文件
     * @param bucketName bucket名称
     * @param objectName 对象名称
     * @param file 上传文件
     * @return 是否上传成功 true 上传成功  false 上传失败
     */
    public boolean uploadFile(String bucketName, String objectName, File file) {
        try (InputStream inputStream = new FileInputStream(file)) {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            if ( StringUtils.isNotEmpty(result.getETag()) ) {
                return true;
            }
        } catch (OSSException oe) {
            throw new RuntimeException(oe.getMessage());
        } catch (ClientException ce) {
            throw new RuntimeException(ce.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return false;
    }

    /**
     * 上传文件
     * @param bucketName bucket名称
     * @param dir 目录名称
     * @return 是否上传成功 true 上传成功  false 上传失败
     */
    public boolean createDir(String bucketName, String dir) {


        try {
            String content = "";

            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, dir, new ByteArrayInputStream(content.getBytes()));

            // 上传字符串。
            ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            throw new RuntimeException(oe.getMessage());
        } catch (ClientException ce) {
            throw new RuntimeException(ce.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return false;
    }


    /**
     * 获取文件访问链接
     * @param bucketName bucket名称
     * @param objectName 对象名称
     * @param expireTime 过期时间 单位：小时
     * @return 文件访问链接
     */
    public String getFileUrl(String bucketName, String objectName, int expireTime) {
        String strUrl = null;
        try {
            // 设置预签名URL过期时间，单位为毫秒。本示例以设置过期时间为1小时为例。
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L * expireTime);
            // 生成以GET方法访问的预签名URL。本示例没有额外请求头，其他人可以直接通过浏览器访问相关内容。
            URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
            strUrl = url.toString();
        } catch (OSSException oe) {
            throw new RuntimeException(oe.getMessage());
        } catch (ClientException ce) {
            throw new RuntimeException(ce.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return strUrl;
    }

}
